Simplify Path
Get the knowledge flowing and circulating! :)
目录
小知识收获:栈的for循环遍历 | StringBuffer | String字符串的判等
思路收获:一开始写这道题的时候,就按照常规思路来思考,/的处理给我带了很大的困扰,然后按照测试样例逐步完善了我的思路。最后还是没能写出代码。看了以前的程序发现处理/的思维是:既然每层之间都要有/,不防把文件名取出,特判处理., ..的情况,最后在输出答案的时候人为地在目录之间加上/即可。
大大简化了问题,最后得到了答案。很棒!
Given a string path, which is an absolute path (starting with a slash '/') to a file or directory in a Unix-style file system, convert it to the simplified canonical path.
In a Unix-style file system, a period '.' refers to the current directory, a double period '..' refers to the directory up a level, and any multiple consecutive slashes (i.e. '//') are treated as a single slash '/'. For this problem, any other format of periods such as '...' are treated as file/directory names.
The canonical path should have the following format:
The path starts with a single slash '/'.
Any two directories are separated by a single slash '/'.
The path does not end with a trailing '/'.
The path only contains the directories on the path from the root directory to the target file or directory (i.e., no period '.' or double period '..')
Return the simplified canonical path.
Example 1:
xxxxxxxxxx31Input: path = "/home/"2Output: "/home"3Explanation: Note that there is no trailing slash after the last directory name.
Example 2:
xxxxxxxxxx31Input: path = "/../"2Output: "/"3Explanation: Going one level up from the root directory is a no-op, as the root level is the highest level you can go.
Example 3:
xxxxxxxxxx31Input: path = "/home//foo/"2Output: "/home/foo"3Explanation: In the canonical path, multiple consecutive slashes are replaced by a single one.
Constraints:
1 <= path.length <= 3000
path consists of English letters, digits, period '.', slash '/' or '_'.
path is a valid absolute Unix path.
xxxxxxxxxx431class Solution {2 public String simplifyPath(String path) {3 4 String[] seg = path.split("/");5 Stack<String> stack = new Stack();6
7 for(String s : seg)8 {9 // System.out.println("-->:|" + s + "|");10 11 // 判断字符串是否相等,用的是equals()方法,不要用"=="12 if (s == "" || s.equals(".")) 13 {14 continue;15 }16 17
18 if (s.equals(".."))19 {20 if (stack.size() > 0)21 {22 stack.pop();23 }24 }25 else26 {27 stack.push(s);28 }29 }30
31 StringBuilder result = new StringBuilder();32 33 // 用这种for循环遍历的方式可以从Stack里把栈底到栈顶的元素打出来~34 for (String dir : stack)35 {36 result.append("/"); // StringBuilder对象有append()方法37 result.append(dir);38 }39
40 // StringBuilder对象有toString()方法41 return result.length() > 0 ? result.toString() : "/";42 }43}
代码解读 | 评价
这个代码写起来还是比较难的,把问题复杂化了。
但是一点点的测试样例让自己的思维越来越丰富,可以明显的发现自己的逻辑思考能力有了些提升。
xxxxxxxxxx341class Solution {2 public String simplifyPath(String path) {3 4 String[] seg = path.split("/");5 Stack<String> stack = new Stack();6
7 for(String s : seg)8 {9 if (s.equals(".."))10 {11 if (!stack.empty())12 {13 stack.pop();14 }15 }16 else if (!s.equals(".") && !s.equals(""))17 {18 stack.push(s);19 }20 // 这里还有个else,但是不用写了,因为什么都不执行,下一轮循环默认忽略了21 // 不添加到栈里,也不pop任何一个栈内元素22 }23
24 StringBuilder result = new StringBuilder();25
26 for (String dir : stack)27 {28 result.append("/");29 result.append(dir);30 }31
32 return result.length() > 0 ? result.toString() : "/";33 }34}代码解读 | 评价
代码2比代码1更简洁;
代码2更能磨练一个人的思维,更清晰;
"/home/"
"/home"
"/../"
"/"
"/home//foo/"
"/home/foo"
"/.././../"
"/"
"/a/b/../c/"
"/a/c"
"/a/./b/../../c/"
"/c"
"/././a/b/c/"
"/a/b/c"
字符串分割
xxxxxxxxxx11 String[] seg = path.split("/");判断字符串相等
xxxxxxxxxx51// 判断字符串是否相等,用的是equals()方法,不要用"=="2if (s == "" || s.equals(".")) 3{4 continue;5}StringBuffer
xxxxxxxxxx111StringBuilder result = new StringBuilder();2 3// 用这种for循环遍历的方式可以从Stack里把栈底到栈顶的元素打出来~4for (String dir : stack)5{6 result.append("/"); // StringBuilder对象有append()方法7 result.append(dir);8}9
10// StringBuilder对象有toString()方法11return result.length() > 0 ? result.toString() : "/"; // 条件表达式